home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 4 / BBS in a Box - Macintosh - Volume IV (January 1992) (BBS in a Box).iso / Files / Prog / T / TransSkel2p.cpt / TransSkel ƒ.np / MultiSkel ƒ / MSkelRgn.p < prev    next >
Encoding:
Text File  |  1988-12-09  |  5.1 KB  |  214 lines  |  [TEXT/PJMM]

  1. {    TransSkel multiple-window demonstration: Region module}
  2.  
  3. {    This module handles a window in which the mouse may be clicked and}
  4. {    dragged to draw rectangles.  The rects so drawn are combined into}
  5. {    a single region, the outline of which is drawn.  Rects drawn while}
  6. {    the shift key is held down are subtracted from the region.}
  7. {    Double-clicking the mouse clears the display.  If the window is}
  8. {    resized, the region that is drawn is resized as well.}
  9.  
  10. {    14 June 1986        Paul DuBois}
  11.  
  12. {    Changes:}
  13. {    07/08/86 Changed outline so that it's drawn as a marquee.}
  14. {    Ported to LightSpeed Pascal 7 January 1987                    }
  15. {    By Owen Hartnett, Ωhm Software                                }
  16. {    30 December 1987 OH changed to support version 1.03 }
  17.  
  18. unit MSkelRgn;
  19. interface
  20.  
  21.     uses
  22. {$IFC UNDEFINED THINK_PASCAL}
  23.         Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf, 
  24. {$ENDC}
  25.         transSkel, multiSkelGlobals, common;
  26.  
  27.     procedure RgnWindInit;
  28.  
  29.  
  30. implementation
  31.  
  32.     var
  33.         rgnPortRect: Rect;    { portRect size - for detecting wind grows }
  34.         selectRgn: RgnHandle;        { current region to be drawn }
  35.         selectWhen: longint;        { time of last click }
  36.         selectWhere: Point;    { location of last click }
  37.         marqueePat: Pattern;
  38.  
  39.     procedure Clobber;
  40.  
  41.     begin
  42.         DisposeRgn(selectRgn);
  43.         CloseWindow(rgnWind);
  44.     end;
  45.  
  46. {    While mouse is down, draw gray selection rectangle in the current}
  47. {    port.  Return the resultant rect in dstRect.  The rect is always}
  48. {    clipped to the current portRect.}
  49.  
  50.  
  51.     procedure DoSelectRect (startPoint: point; var dstRect: Rect);
  52.  
  53.         var
  54.             pt, dragPt: Point;
  55.             rClip: Rect;
  56.             thePort: GrafPtr;
  57.             result: Boolean;
  58.             ps: PenState;
  59.             i: integer;
  60.  
  61.     begin
  62.         GetPort(thePort);
  63.         rClip := thePort^.portRect;
  64.         rClip.right := rClip.right - 15;
  65.         GetPenState(ps);
  66.         PenPat(gray);
  67.         PenMode(patXor);
  68.         dragPt := startPoint;
  69.         Pt2Rect(dragPt, dragPt, dstRect);
  70.         FrameRect(dstRect);
  71.         while StillDown do
  72.             begin
  73.                 GetMouse(pt);
  74.                 if not EqualPt(pt, dragPt) then    { mouse has moved, change region }
  75.                     begin
  76.                         FrameRect(dstRect);
  77.                         dragPt := pt;
  78.                         Pt2Rect(dragPt, startPoint, dstRect);
  79.                         result := SectRect(dstRect, rClip, dstRect);
  80.                         FrameRect(dstRect);
  81.                         for i := 0 to 1000 do
  82.                             ;
  83.                     end;
  84.             end;
  85.         FrameRect(dstRect);    { erase last rect }
  86.         SetPenState(ps);
  87.     end;
  88.  
  89.     procedure MarqueeRgn (r: RgnHandle);
  90.  
  91.         var
  92.             p: PenState;
  93.             b: Byte;
  94.             i: integer;
  95.  
  96.     begin
  97.         GetPenState(p);
  98.         PenPat(marqueePat);
  99.         PenMode(patCopy);
  100.         FrameRgn(r);
  101.         SetPenState(p);
  102.         b := marqueePat[0];        { shift pattern for next call }
  103.         for i := 0 to 6 do
  104.             marqueePat[i] := marqueePat[i + 1];
  105.         marqueePat[7] := b;
  106.     end;
  107.  
  108.     procedure Idle;
  109.  
  110.         var
  111.             i: integer;
  112.  
  113.     begin
  114.         SetWindClip(rgnWind);
  115.         MarqueeRgn(selectRgn);    { draw selection region outline }
  116.         ResetWindClip;            { restore previous clipping }
  117.     end;
  118.  
  119. {    On double-click, clear window.  On single click, draw gray selection}
  120. {    rectangle as long as mouse is held down.  If user draws non-empty rect,}
  121. {    then add it to the selection region and redraw the region's outline.}
  122. {    If the shift-key was down, then subtract the selection region instead}
  123. {    and redraw.}
  124.  
  125.  
  126.     procedure Mouse (thePt: Point; t: longint; mods: integer);
  127.  
  128.         var
  129.             r: Rect;
  130.             rgn: RgnHandle;
  131.  
  132.     begin
  133.         r := rgnWind^.portRect;
  134.         if thePt.h < r.right - 15 then        { must not click in right edge }
  135.             begin
  136.                 if (t - selectWhen <= GetDblTime) then    { it's a double-click }
  137.                     begin
  138.                         selectWhen := 0;        { don't take next click as dbl-click }
  139.                         SetWindClip(rgnWind);
  140.                         EraseRgn(selectRgn);
  141.                         ResetWindClip;
  142.                         SetEmptyRgn(selectRgn);    { clear region }
  143.                     end
  144.                 else
  145.                     begin
  146.                         selectWhen := t;                { update click variables }
  147.                         selectWhere := thePt;
  148.                         DoSelectRect(thePt, r);    { draw selection rectangle }
  149.                         if not EmptyRect(r) then
  150.                             begin
  151.                                 EraseRgn(selectRgn);
  152.                                 selectWhen := 0;
  153.                                 rgn := NewRgn;
  154.                                 RectRgn(rgn, r);
  155.                                 if (Bitand(mods, shiftKey)) <> 0 then        { test shift key }
  156.                                     DiffRgn(selectRgn, rgn, selectRgn)
  157.                                 else
  158.                                     unionRgn(selectRgn, rgn, selectRgn);
  159.                                 DisposeRgn(rgn);
  160.                             end;
  161.                     end;
  162.             end;
  163.     end;
  164.  
  165. {    Redraw the current region.  If the window was resized, resize}
  166. {    the region to fit.}
  167.  
  168.     procedure Update (resized: Boolean);
  169.  
  170.         var
  171.             r: Rect;
  172.  
  173.     begin
  174.         EraseRect(rgnWind^.portRect);
  175.         if resized then
  176.             begin
  177.                 r := rgnWind^.portRect;
  178.                 rgnPortRect.right := rgnPortrect.right - 15;    { don't use right edge of window }
  179.                 r.right := r.right - 15;
  180.                 MapRgn(selectRgn, rgnPortRect, r);
  181.                 rgnPortRect := rgnWind^.portRect
  182.             end;
  183.         DrawGrowBox(rgnWind);
  184.         idle;
  185.     end;
  186.  
  187.     procedure Activate (active: Boolean);
  188.  
  189.     begin
  190.         DrawGrowBox(rgnWind);
  191.         if active then
  192.             DisableItem(editMenu, 0)
  193.         else
  194.             EnableItem(editMenu, 0);
  195.         DrawMenuBar;
  196.     end;
  197.  
  198.     procedure RgnWindInit;
  199.  
  200.     begin
  201.         StuffHex(@marqueePat, '0f87c3e1f0783c1e');
  202.         rgnWind := GetNewWindow(rgnWindRes, nil, WindowPtr(-1));
  203.         dummy := SkelWindow(rgnWind, @Mouse, nil, @update, @activate, nil, @Clobber, @Idle, true);
  204.         { ignore keyclicks }
  205.         { no close proc }
  206.     { disposal proc }
  207.         { idle proc }
  208.  
  209.         rgnPortRect := rgnWind^.portRect;
  210.         selectRgn := NewRgn;    { selected region empty initially }
  211.  
  212.         selectWhen := 0;    { first click can't be taken as dbl-click }
  213.     end;
  214. end.